package com.example.springbootp6spy.config;

import com.p6spy.engine.common.P6Util;
import com.p6spy.engine.spy.appender.MessageFormattingStrategy;

import java.text.SimpleDateFormat;
import java.util.Date;

import static com.example.springbootp6spy.config.constant.P6spyConstant.*;

/**
 * P6spy配置类 设置自定义控制台打印完整Sql日志格式
 *
 * @author Lv
 * @date 2022/10/3
 */
public class P6spySqlLogConfig implements MessageFormattingStrategy {
    /**
     * 自定义Sql日志
     *
     * @param connectionId 连接id
     * @param now          当前时间
     * @param elapsed      耗时多久
     * @param category     类别
     * @param prepared     mybatis带占位符的sql
     * @param sql          占位符换成参数的sql
     * @param url          sql连接的 url
     * @return
     */
    @Override
    public String formatMessage(int connectionId, String now, long elapsed, String category, String prepared, String sql, String url) {
        return !"".equals(sql.trim()) ? new SimpleDateFormat(DATE_FORMAT).format(new Date()) + " | took " + elapsed + "ms | " + category
                + " | connection " + connectionId + formatSql(P6Util.singleLine(SPACE + sql)) + ";" + NEW_LINE + LINE : "";
    }

    /**
     * 格式化SQL
     *
     * @param sql DML语句
     * @return 格式化过后的Sql
     */
    @SuppressWarnings("all")
    private String formatSql(String sql) {
        // 处理占位符
        String sqlString = sql
                .replaceAll(SPACE_XML, SPACE)
                .replaceAll(NULL_LINE, SPACE);

        // 处理小写关键字
        String sqlLowerCase = sqlString
                .replaceAll(SELECT_LOWERCASE, NEW_LINE + SELECT_LOWERCASE + NEW_LINE)
                .replaceAll(FROM_LOWERCASE, NEW_LINE + FROM_LOWERCASE + NEW_LINE)
                .replaceAll(WHERE_LOWERCASE, NEW_LINE + WHERE_LOWERCASE + NEW_LINE)
                .replaceAll(ORDER_LOWERCASE, NEW_LINE + ORDER_LOWERCASE)
                .replaceAll(GROUP_LOWERCASE, NEW_LINE + GROUP_LOWERCASE)
                .replaceAll(UNION_LOWERCASE, NEW_LINE + UNION_LOWERCASE)
                .replaceAll(INSERT_LOWERCASE, NEW_LINE + INSERT_LOWERCASE)
                .replaceAll(INTO_LOWERCASE, INTO_LOWERCASE + NEW_LINE)
                .replaceAll(VALUES_LOWERCASE, NEW_LINE + VALUES_LOWERCASE + NEW_LINE)
                .replaceAll(UPDATE_LOWERCASE, NEW_LINE + UPDATE_LOWERCASE + NEW_LINE)
                .replaceAll(SET_LOWERCASE, NEW_LINE + SET_LOWERCASE + NEW_LINE)
                .replaceAll(DELETE_LOWERCASE, NEW_LINE + DELETE_LOWERCASE);

        // 处理大写关键字
        String sqlUpperCase = sqlLowerCase
                .replaceAll(DELETE_UPPERCASE, NEW_LINE + DELETE_LOWERCASE)
                .replaceAll(SELECT_UPPERCASE, NEW_LINE + SELECT_LOWERCASE + NEW_LINE)
                .replaceAll(FROM_UPPERCASE, NEW_LINE + FROM_LOWERCASE + NEW_LINE)
                .replaceAll(WHERE_UPPERCASE, NEW_LINE + WHERE_LOWERCASE + NEW_LINE)
                .replaceAll(ORDER_UPPERCASE, NEW_LINE + ORDER_LOWERCASE)
                .replaceAll(GROUP_UPPERCASE, NEW_LINE + GROUP_LOWERCASE)
                .replaceAll(UNION_UPPERCASE, NEW_LINE + UNION_LOWERCASE)
                .replaceAll(INSERT_UPPERCASE, NEW_LINE + INSERT_LOWERCASE)
                .replaceAll(INTO_UPPERCASE, INTO_LOWERCASE + NEW_LINE)
                .replaceAll(VALUES_UPPERCASE, NEW_LINE + VALUES_LOWERCASE + NEW_LINE)
                .replaceAll(UPDATE_UPPERCASE, NEW_LINE + UPDATE_LOWERCASE + NEW_LINE)
                .replaceAll(SET_UPPERCASE, NEW_LINE + SET_LOWERCASE + NEW_LINE);

        return sqlUpperCase;
    }
}